# Copyright 2020 Google LLC
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
#
# Description:
#   XNNPACK - optimized floating-point neural network operators library

load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@bazel_skylib//lib:selects.bzl", "selects")  # buildifier: disable=out-of-order-load
load("@rules_python//python:py_binary.bzl", "py_binary")
load(
    ":build_defs.bzl",
    "xnnpack_cc_library",
    "xnnpack_cxx_library",
    "xnnpack_if_kleidiai_enabled",
    "xnnpack_min_size_copts",
    "xnnpack_slinky_deps",
    "xnnpack_slinky_srcs",
    "xnnpack_std_cxxopts",
    "xnnpack_transitive_source_list",
    "xnnpack_visibility",
)
load(
    ":build_params.bzl",
    "xnnpack_archs",
    "xnnpack_cc_library_for_arch",
    "xnnpack_cond_for_arch",
    "xnnpack_configurable_defines",
    "xnnpack_list_sum",
    "xnnpack_select_if",
    "xnnpack_simd_f16_archs",
    "xnnpack_simd_f32_archs",
    "xnnpack_simd_s16_archs",
    "xnnpack_simd_s32_archs",
    "xnnpack_simd_s8_archs",
)
load(
    "//gen:microkernels.bzl",
    "all_srcs_for_arch",
    "non_prod_asm_srcs_for_arch",
    "non_prod_c_srcs_for_arch",
    "prod_asm_srcs_for_arch",
    "prod_c_srcs_for_arch",
)

licenses(["notice"])

exports_files(["LICENSE"])

exports_files(["preamble.js.lds"])

OPERATOR_SRCS = [
    "src/operator-delete.c",
    "src/operator-run.c",
    "src/operators/argmax-pooling-nhwc.c",
    "src/operators/average-pooling-nhwc.c",
    "src/operators/batch-matrix-multiply-nc.c",
    "src/operators/binary-elementwise-nd.c",
    "src/operators/channel-shuffle-nc.c",
    "src/operators/constant-pad-nd.c",
    "src/operators/convolution-nchw.c",
    "src/operators/convolution-nhwc.c",
    "src/operators/deconvolution-nhwc.c",
    "src/operators/dynamic-fully-connected-nc.c",
    "src/operators/fully-connected-nc.c",
    "src/operators/global-average-pooling-ncw.c",
    "src/operators/global-average-pooling-nwc.c",
    "src/operators/lut-elementwise-nc.c",
    "src/operators/max-pooling-nhwc.c",
    "src/operators/prelu-nc.c",
    "src/operators/reduce-nd.c",
    "src/operators/resize-bilinear-nchw.c",
    "src/operators/resize-bilinear-nhwc.c",
    "src/operators/rope-nthc.c",
    "src/operators/scaled-dot-product-attention-nhtc.c",
    "src/operators/slice-nd.c",
    "src/operators/softmax-nc.c",
    "src/operators/transpose-nd.c",
    "src/operators/unary-elementwise-nc.c",
    "src/operators/unpooling-nhwc.c",
]

SUBGRAPH_SRCS = [
    "src/memory-planner.c",
    "src/runtime.c",
    "src/subgraph.c",
    "src/subgraph/abs.c",
    "src/subgraph/add2.c",
    "src/subgraph/argmax-pooling-2d.c",
    "src/subgraph/average-pooling-2d.c",
    "src/subgraph/bankers-rounding.c",
    "src/subgraph/batch-matrix-multiply.c",
    "src/subgraph/ceiling.c",
    "src/subgraph/clamp.c",
    "src/subgraph/concatenate.c",
    "src/subgraph/convert.c",
    "src/subgraph/convolution-2d.c",
    "src/subgraph/copy.c",
    "src/subgraph/copysign.c",
    "src/subgraph/deconvolution-2d.c",
    "src/subgraph/depth-to-space-2d.c",
    "src/subgraph/depthwise-convolution-2d.c",
    "src/subgraph/divide.c",
    "src/subgraph/elu.c",
    "src/subgraph/even-split.c",
    "src/subgraph/exp.c",
    "src/subgraph/floor.c",
    "src/subgraph/fully-connected-sparse.c",
    "src/subgraph/fully-connected.c",
    "src/subgraph/gelu.c",
    "src/subgraph/global-average-pooling.c",
    "src/subgraph/global-sum-pooling.c",
    "src/subgraph/hardswish.c",
    "src/subgraph/leaky-relu.c",
    "src/subgraph/log.c",
    "src/subgraph/max-pooling-2d.c",
    "src/subgraph/maximum2.c",
    "src/subgraph/minimum2.c",
    "src/subgraph/multiply2.c",
    "src/subgraph/negate.c",
    "src/subgraph/prelu.c",
    "src/subgraph/reciprocal-square-root.c",
    "src/subgraph/reshape-helpers.c",
    "src/subgraph/rope.c",
    "src/subgraph/scaled-dot-product-attention.c",
    "src/subgraph/sigmoid.c",
    "src/subgraph/softmax.c",
    "src/subgraph/space-to-depth-2d.c",
    "src/subgraph/square-root.c",
    "src/subgraph/square.c",
    "src/subgraph/squared-difference.c",
    "src/subgraph/static-constant-pad.c",
    "src/subgraph/static-mean.c",
    "src/subgraph/static-resize-bilinear-2d.c",
    "src/subgraph/static-slice.c",
    "src/subgraph/static-transpose.c",
    "src/subgraph/subtract.c",
    "src/subgraph/tanh.c",
    "src/subgraph/unpooling-2d.c",
    "src/subgraph/validation.c",
    "src/tensor.c",
]

TABLE_SRCS = [
    "src/tables/exp2-k-over-64.c",
    "src/tables/exp2-k-over-2048.c",
    "src/tables/exp2minus-k-over-4.c",
    "src/tables/exp2minus-k-over-8.c",
    "src/tables/exp2minus-k-over-16.c",
    "src/tables/exp2minus-k-over-32.c",
    "src/tables/exp2minus-k-over-64.c",
    "src/tables/exp2minus-k-over-2048.c",
    "src/tables/vlog.c",
]

MICROKERNEL_DEFS = [
    "src/bf16-vabs/bf16-vabs.h",
    "src/f16-avgpool/f16-avgpool-minmax.h",
    "src/f16-maxpool/f16-maxpool-minmax.h",
    "src/f16-pavgpool/f16-pavgpool-minmax.h",
    "src/f16-vabs/f16-vabs.h",
    "src/f16-vbinary/f16-vadd-minmax.h",
    "src/f16-vbinary/f16-vaddc-minmax.h",
    "src/f16-vbinary/f16-vcmul.h",
    "src/f16-vbinary/f16-vdiv-minmax.h",
    "src/f16-vbinary/f16-vdivc-minmax.h",
    "src/f16-vbinary/f16-vmax.h",
    "src/f16-vbinary/f16-vmaxc.h",
    "src/f16-vbinary/f16-vmin.h",
    "src/f16-vbinary/f16-vminc.h",
    "src/f16-vbinary/f16-vmul-minmax.h",
    "src/f16-vbinary/f16-vmulc-minmax.h",
    "src/f16-vbinary/f16-vrdivc-minmax.h",
    "src/f16-vbinary/f16-vrsubc-minmax.h",
    "src/f16-vbinary/f16-vsqrdiff.h",
    "src/f16-vbinary/f16-vsqrdiffc.h",
    "src/f16-vbinary/f16-vsub-minmax.h",
    "src/f16-vbinary/f16-vsubc-minmax.h",
    "src/f16-vbinary/f16-vprelu.h",
    "src/f16-vbinary/f16-vpreluc.h",
    "src/f16-vbinary/f16-vrpreluc.h",
    "src/f16-vclamp/f16-vclamp.h",
    "src/f16-velu/f16-velu.h",
    "src/f16-vhswish/f16-vhswish.h",
    "src/f16-vlrelu/f16-vlrelu.h",
    "src/f16-vneg/f16-vneg.h",
    "src/f16-vrnd/f16-vrndd.h",
    "src/f16-vrnd/f16-vrndne.h",
    "src/f16-vrnd/f16-vrndu.h",
    "src/f16-vrnd/f16-vrndz.h",
    "src/f16-vrsqrt/f16-vrsqrt.h",
    "src/f16-vsigmoid/f16-vsigmoid.h",
    "src/f16-vsqr/f16-vsqr.h",
    "src/f16-vsqrt/f16-vsqrt.h",
    "src/f16-vtanh/f16-vtanh.h",
    "src/f32-avgpool/f32-avgpool-minmax.h",
    "src/f32-maxpool/f32-maxpool-minmax.h",
    "src/f32-pavgpool/f32-pavgpool-minmax.h",
    "src/f32-vabs/f32-vabs.h",
    "src/f32-vbinary/f32-vadd-minmax.h",
    "src/f32-vbinary/f32-vadd-relu.h",
    "src/f32-vbinary/f32-vadd.h",
    "src/f32-vbinary/f32-vaddc-minmax.h",
    "src/f32-vbinary/f32-vaddc-relu.h",
    "src/f32-vbinary/f32-vaddc.h",
    "src/f32-vbinary/f32-vcmul.h",
    "src/f32-vbinary/f32-vcopysign.h",
    "src/f32-vbinary/f32-vcopysignc.h",
    "src/f32-vbinary/f32-vdiv-minmax.h",
    "src/f32-vbinary/f32-vdiv-relu.h",
    "src/f32-vbinary/f32-vdiv.h",
    "src/f32-vbinary/f32-vdivc-minmax.h",
    "src/f32-vbinary/f32-vdivc-relu.h",
    "src/f32-vbinary/f32-vdivc.h",
    "src/f32-vbinary/f32-vmax.h",
    "src/f32-vbinary/f32-vmaxc.h",
    "src/f32-vbinary/f32-vmin.h",
    "src/f32-vbinary/f32-vminc.h",
    "src/f32-vbinary/f32-vmul-minmax.h",
    "src/f32-vbinary/f32-vmul-relu.h",
    "src/f32-vbinary/f32-vmul.h",
    "src/f32-vbinary/f32-vmulc-minmax.h",
    "src/f32-vbinary/f32-vmulc-relu.h",
    "src/f32-vbinary/f32-vmulc.h",
    "src/f32-vbinary/f32-vrcopysignc.h",
    "src/f32-vbinary/f32-vrdivc-minmax.h",
    "src/f32-vbinary/f32-vrdivc-relu.h",
    "src/f32-vbinary/f32-vrdivc.h",
    "src/f32-vbinary/f32-vrsubc-minmax.h",
    "src/f32-vbinary/f32-vrsubc-relu.h",
    "src/f32-vbinary/f32-vrsubc.h",
    "src/f32-vbinary/f32-vsqrdiff.h",
    "src/f32-vbinary/f32-vsqrdiffc.h",
    "src/f32-vbinary/f32-vsub-minmax.h",
    "src/f32-vbinary/f32-vsub-relu.h",
    "src/f32-vbinary/f32-vsub.h",
    "src/f32-vbinary/f32-vsubc-minmax.h",
    "src/f32-vbinary/f32-vsubc-relu.h",
    "src/f32-vbinary/f32-vsubc.h",
    "src/f32-vbinary/f32-vprelu.h",
    "src/f32-vbinary/f32-vpreluc.h",
    "src/f32-vbinary/f32-vrpreluc.h",
    "src/f32-vclamp/f32-vclamp.h",
    "src/f32-velu/f32-velu.h",
    "src/f32-vexp/f32-vexp.h",
    "src/f32-vgelu/f32-vgelu.h",
    "src/f32-vhswish/f32-vhswish.h",
    "src/f32-vlog/f32-vlog.h",
    "src/f32-vlrelu/f32-vlrelu.h",
    "src/f32-vneg/f32-vneg.h",
    "src/f32-vrelu/f32-vrelu.h",
    "src/f32-vrnd/f32-vrndd.h",
    "src/f32-vrnd/f32-vrndne.h",
    "src/f32-vrnd/f32-vrndu.h",
    "src/f32-vrnd/f32-vrndz.h",
    "src/f32-vrsqrt/f32-vrsqrt.h",
    "src/f32-vsigmoid/f32-vsigmoid.h",
    "src/f32-vsqr/f32-vsqr.h",
    "src/f32-vsqrt/f32-vsqrt.h",
    "src/f32-vtanh/f32-vtanh.h",
    "src/qs8-vadd/qs8-vadd-minmax.h",
    "src/qs8-vaddc/qs8-vaddc-minmax.h",
    "src/qs8-vhswish/qs8-vhswish.h",
    "src/qs8-vlrelu/qs8-vlrelu.h",
    "src/qs8-vmul/qs8-vmul-minmax-fp32.h",
    "src/qs8-vmul/qs8-vmul-minmax-rndnu.h",
    "src/qs8-vmulc/qs8-vmulc-minmax-fp32.h",
    "src/qs8-vmulc/qs8-vmulc-minmax-rndnu.h",
    "src/qu8-avgpool/qu8-avgpool-minmax.h",
    "src/qu8-vadd/qu8-vadd-minmax.h",
    "src/qu8-vaddc/qu8-vaddc-minmax.h",
    "src/qu8-vhswish/qu8-vhswish.h",
    "src/qu8-vlrelu/qu8-vlrelu.h",
    "src/qu8-vmul/qu8-vmul-minmax-fp32.h",
    "src/qu8-vmul/qu8-vmul-minmax-rndnu.h",
    "src/qu8-vmulc/qu8-vmulc-minmax-fp32.h",
    "src/qu8-vmulc/qu8-vmulc-minmax-rndnu.h",
    "src/s8-maxpool/s8-maxpool-minmax.h",
    "src/s8-vclamp/s8-vclamp.h",
    "src/s32-vmul/s32-vmul.h",
    "src/s32-vmul/s32-vmulc.h",
    "src/u8-maxpool/u8-maxpool-minmax.h",
    "src/u8-vclamp/u8-vclamp.h",
    "src/u64-u32-vsqrtshift/u64-u32-vsqrtshift.h",
    "src/x8-packq/x8-packq.h",
    "src/x8-packw/x8-packw.h",
    "src/qs8-packw/qs8-packw.h",
    "src/x16-packw/x16-packw.h",
    "src/x32-packb/x32-packb.h",
    "src/x32-packw/x32-packw.h",
    "src/x32-packx/x32-packx.h",
    "src/x32-zerob/x32-zerob.h",
]

MICROKERNEL_HDRS = [
    "src/xnnpack/argmaxpool.h",
    "src/xnnpack/avgpool.h",
    "src/xnnpack/conv.h",
    "src/xnnpack/dwconv.h",
    "src/xnnpack/fft.h",
    "src/xnnpack/fill.h",
    "src/xnnpack/filterbank.h",
    "src/xnnpack/gavgpool.h",
    "src/xnnpack/gemm.h",
    "src/xnnpack/ibilinear.h",
    "src/xnnpack/igemm.h",
    "src/xnnpack/lut.h",
    "src/xnnpack/maxpool.h",
    "src/xnnpack/packb.h",
    "src/xnnpack/packq.h",
    "src/xnnpack/packw.h",
    "src/xnnpack/packx.h",
    "src/xnnpack/pad.h",
    "src/xnnpack/pavgpool.h",
    "src/xnnpack/ppmm.h",
    "src/xnnpack/prelu.h",
    "src/xnnpack/quantization.h",
    "src/xnnpack/raddexpminusmax.h",
    "src/xnnpack/raddextexp.h",
    "src/xnnpack/raddstoreexpminusmax.h",
    "src/xnnpack/reduce.h",
    "src/xnnpack/rmaxabs.h",
    "src/xnnpack/spmm.h",
    "src/xnnpack/transpose.h",
    "src/xnnpack/unpool.h",
    "src/xnnpack/vbinary.h",
    "src/xnnpack/vcvt.h",
    "src/xnnpack/vhswish.h",
    "src/xnnpack/vlog.h",
    "src/xnnpack/vlrelu.h",
    "src/xnnpack/vlshift.h",
    "src/xnnpack/vmulcaddc.h",
    "src/xnnpack/vscaleexpminusmax.h",
    "src/xnnpack/vscaleextexp.h",
    "src/xnnpack/vsquareabs.h",
    "src/xnnpack/vunary.h",
    "src/xnnpack/window.h",
    "src/xnnpack/zerob.h",
    "src/xnnpack/zip.h",
] + MICROKERNEL_DEFS

MICROKERNEL_DEPS = [
    ":assembly",
    ":common",
    ":hardware_config",
    ":logging",
    ":math",
    ":microkernels_h",
    ":microparams",
    ":prefetch",
    ":tables",
    ":unaligned",
]

SIMD_HEADERS = [
    "src/xnnpack/simd/f32-avx-base.h",
    "src/xnnpack/simd/f32-generic-functions.h",
] + [
    "src/xnnpack/simd/f32-" + arch + ".h"
    for arch in xnnpack_simd_f32_archs()
] + [
    "src/xnnpack/simd/f16-" + arch + ".h"
    for arch in xnnpack_simd_f16_archs()
] + [
    "src/xnnpack/simd/s16-" + arch + ".h"
    for arch in xnnpack_simd_s16_archs()
] + [
    "src/xnnpack/simd/s32-" + arch + ".h"
    for arch in xnnpack_simd_s32_archs()
] + [
    "src/xnnpack/simd/s8-" + arch + ".h"
    for arch in xnnpack_simd_s8_archs()
]

exports_files(SIMD_HEADERS)

INTERNAL_MICROKERNEL_HDRS = MICROKERNEL_HDRS + SIMD_HEADERS + [
    "src/xnnpack/cache.h",
    "src/xnnpack/intrinsics-polyfill.h",
    "src/xnnpack/requantization-stubs.h",
    "src/xnnpack/unaligned.h",
]

ALL_MICROKERNEL_SRCS = xnnpack_list_sum(
    [all_srcs_for_arch(arch) for arch in xnnpack_archs()],
    [],
)

filegroup(
    name = "microkernel_source_files",
    data = ALL_MICROKERNEL_SRCS + ["src/microparams-init.c"],
    visibility = xnnpack_visibility(),
)

filegroup(
    name = "microkernel_header_files",
    data = MICROKERNEL_HDRS + ["src/xnnpack/microparams.h"],
    visibility = xnnpack_visibility(),
)

# Collection of internal microkernel related headers that declares all the microkernel functions.
xnnpack_cc_library(
    name = "microkernels_h",
    hdrs = INTERNAL_MICROKERNEL_HDRS,
    deps = [
        ":common",
        ":config_hdrs",
        ":math",
        ":memory",
        ":microparams",
        ":mutex",
        ":xnnpack_h",
        "@FP16",
    ],
)

xnnpack_cc_library(
    name = "xnnpack_h",
    hdrs = ["include/xnnpack.h"],
    deps = [
        "@pthreadpool",
    ],
)

xnnpack_cc_library(
    name = "experiments_config",
    srcs = ["src/configs/experiments-config.c"],
    hdrs = ["include/experiments-config.h"],
    visibility = xnnpack_visibility(),
)

xnnpack_cc_library(
    name = "common",
    hdrs = ["src/xnnpack/common.h"],
)

xnnpack_cc_library(
    name = "init_once",
    hdrs = ["src/xnnpack/init-once.h"],
    deps = [
        ":common",
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "microparams",
    hdrs = [
        "src/xnnpack/microparams.h",
    ],
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "hardware_config",
    srcs = ["src/configs/hardware-config.c"],
    hdrs = [
        "src/xnnpack/hardware-config.h",
        "src/xnnpack/microfnptr.h",
        "src/xnnpack/microparams.h",
    ],
    defines = xnnpack_configurable_defines(),
    deps = [
        ":common",
        ":init_once",
        ":logging",
    ] + select({
        ":cpuinfo_enabled": ["@cpuinfo"],
        "//conditions:default": [],
    }),
)

xnnpack_cc_library(
    name = "config_hdrs",
    hdrs = [
        "src/xnnpack/config.h",
        "src/xnnpack/config-types.h",
    ],
    deps = [
        ":hardware_config",
        ":params",
    ],
)

xnnpack_cc_library(
    name = "microkernel_configs",
    srcs = [
        "src/configs/argmaxpool-config.c",
        "src/configs/avgpool-config.c",
        "src/configs/binary-elementwise-config.c",
        "src/configs/cmul-config.c",
        "src/configs/conv-hwc2chw-config.c",
        "src/configs/dwconv-config.c",
        "src/configs/dwconv2d-chw-config.c",
        "src/configs/gavgpool-config.c",
        "src/configs/gavgpool-cw-config.c",
        "src/configs/gemm-config.c",
        "src/configs/ibilinear-chw-config.c",
        "src/configs/ibilinear-config.c",
        "src/configs/lut32norm-config.c",
        "src/configs/maxpool-config.c",
        "src/configs/pavgpool-config.c",
        "src/configs/prelu-config.c",
        "src/configs/raddstoreexpminusmax-config.c",
        "src/configs/reduce-config.c",
        "src/configs/rmax-config.c",
        "src/configs/spmm-config.c",
        "src/configs/transpose-config.c",
        "src/configs/unary-elementwise-config.c",
        "src/configs/unpool-config.c",
        "src/configs/vmulcaddc-config.c",
        "src/configs/x8-lut-config.c",
        "src/configs/xx-fill-config.c",
        "src/configs/xx-pad-config.c",
        "src/configs/zip-config.c",
    ],
    hdrs = [
        "src/xnnpack/config.h",
        "src/xnnpack/config-types.h",
        "src/xnnpack/microfnptr.h",
        "src/xnnpack/microparams.h",
    ],
    copts = select({
        ":cpuinfo_enabled": ["-DXNN_ENABLE_CPUINFO=1"],
        "//conditions:default": ["-DXNN_ENABLE_CPUINFO=0"],
    }),
    defines = xnnpack_configurable_defines(),
    deps = [
        ":common",
        ":config_hdrs",
        ":experiments_config",
        ":hardware_config",
        ":init_once",
        ":logging",
        ":math",
        ":microkernels_h",
        ":microparams_init",
        ":packing",
        ":prod_microkernels",
        "@FP16",
    ] + select({
        ":cpuinfo_enabled": ["@cpuinfo"],
        "//conditions:default": [],
    }),
)

xnnpack_cc_library(
    name = "params",
    srcs = ["src/params.c"],
    hdrs = [
        "src/xnnpack/microfnptr.h",
        "src/xnnpack/params.h",
    ],
    deps = [
        ":common",
        ":microparams",
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "math",
    hdrs = ["src/xnnpack/math.h"],
    deps = [
        ":common",
        ":config_hdrs",
        "@FP16",
    ],
)

xnnpack_cc_library(
    name = "prefetch",
    hdrs = ["src/xnnpack/prefetch.h"],
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "unaligned",
    hdrs = ["src/xnnpack/unaligned.h"],
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "microparams_init",
    srcs = ["src/microparams-init.c"],
    hdrs = ["src/xnnpack/microparams-init.h"],
    deps = [
        ":common",
        ":logging",
        ":math",
        ":microparams",
        ":unaligned",
        ":xnnpack_h",
        "@FP16",
    ],
)

xnnpack_cc_library(
    name = "node_type",
    hdrs = ["src/xnnpack/node-type.h"],
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "allocation_type",
    hdrs = ["src/xnnpack/allocation-type.h"],
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "operator_type",
    hdrs = ["src/xnnpack/operator-type.h"],
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "microkernel_type",
    hdrs = ["src/xnnpack/microkernel-type.h"],
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "internal",
    hdrs = ["src/xnnpack/internal.h"],
    deps = [
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "allocator",
    srcs = [
        "src/allocator.c",
    ],
    hdrs = ["src/xnnpack/allocator.h"],
    deps = [
        ":common",
        ":logging",
        ":math",
        ":params",
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "aligned_allocator",
    hdrs = [
        "src/xnnpack/aligned-allocator.h",
    ],
)

xnnpack_cc_library(
    name = "isa_checks",
    hdrs = [
        "src/xnnpack/isa-checks.h",
    ],
    deps = [
        ":common",
        ":hardware_config",
    ],
)

xnnpack_cc_library(
    name = "memory",
    srcs = [
        "src/memory.c",
    ],
    hdrs = ["src/xnnpack/memory.h"],
    # Override using xnnpack_gcc_std_copts, as it defines -std=c99, which then makes MAP_ANONYMOUS
    # undefined
    gcc_copts = [],
    deps = [
        ":common",
        ":logging",
        ":math",
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "quantization",
    hdrs = ["src/xnnpack/quantization.h"],
    deps = [
        ":common",
        ":math",
        ":microparams",
        "@FP16",
    ],
)

xnnpack_cc_library(
    name = "requantization",
    hdrs = ["src/xnnpack/requantization.h"],
    deps = [
        ":common",
        ":math",
        ":microparams",
    ],
)

xnnpack_cc_library(
    name = "requantization_stubs",
    hdrs = ["src/xnnpack/requantization-stubs.h"],
)

xnnpack_cc_library(
    name = "tables",
    srcs = TABLE_SRCS,
    deps = [
        ":common",
    ],
)

xnnpack_cc_library(
    name = "assembly",
    hdrs = ["src/xnnpack/assembly.h"],
    compatible_with = [],
)

genrule(
    name = "generated_microkernel_lists",
    srcs = glob([
        "**/*.c",
        "**/*.cc",
        "**/*.S",
    ]),
    outs = ([
                "testdata/gen/microkernels.bzl",
                "testdata/cmake/gen/microkernels.cmake",
            ] + ["testdata/gen/" + arch + "_microkernels.bzl" for arch in xnnpack_archs()] +
            ["testdata/cmake/gen/" + arch + "_microkernels.cmake" for arch in xnnpack_archs()]),
    cmd = ("$(location //tools:update_microkernels) " +
           "--output $(RULEDIR)/testdata " +
           "--root_dir %s" % (package_name() if package_name() else ".")),
    compatible_with = [],
    tools = ["//tools:update_microkernels"],
    visibility = ["//:__subpackages__"],
)

filegroup(
    name = "cmake_microkernel_lists",
    srcs = glob([
        "cmake/gen/*.cmake",
    ]),
    visibility = ["//:__subpackages__"],
)

# Generate the prod/all microkernel libraries for each architecture.
[
    [
        genrule(
            name = arch + "_prod_microkernel_srcs",
            srcs = prod_c_srcs_for_arch(arch),
            outs = [arch + "_prod_microkernels.c"],
            cmd = "cat $(SRCS) > $@",
            compatible_with = [],
        ),
        genrule(
            name = arch + "_non_prod_microkernel_srcs",
            srcs = non_prod_c_srcs_for_arch(arch),
            outs = [arch + "_non_prod_microkernels.c"],
            cmd = "cat $(SRCS) > $@",
            compatible_with = [],
        ),
        xnnpack_cc_library_for_arch(
            name = arch + "_prod_microkernels",
            srcs = prod_asm_srcs_for_arch(arch) + [":" + arch + "_prod_microkernel_srcs"],
            arch = arch,
            compatible_with = [],
            defines = xnnpack_configurable_defines(),
            tags = ["nobuilder"],
            deps = MICROKERNEL_DEPS,
        ),
        xnnpack_cc_library_for_arch(
            name = arch + "_all_microkernels",
            srcs = non_prod_asm_srcs_for_arch(arch) + [":" + arch + "_non_prod_microkernel_srcs"],
            arch = arch,
            compatible_with = [],
            defines = xnnpack_configurable_defines(),
            tags = ["nobuilder"],
            deps = MICROKERNEL_DEPS + [":" + arch + "_prod_microkernels"],
        ),
    ]
    for arch in xnnpack_archs()
]

xnnpack_cc_library(
    name = "log_level_default",
    defines = select({
        # No logging in optimized mode
        ":optimized_build": ["XNN_LOG_LEVEL=0"],
        # Info logging in debug mode.  Use `--define=xnn_log_level=debug` for full logging.
        ":debug_build": ["XNN_LOG_LEVEL=4"],
        # Error-only logging in default (fastbuild) mode
        "//conditions:default": ["XNN_LOG_LEVEL=2"],
    }),
)

xnnpack_cc_library(
    name = "logging",
    srcs = [
        "src/enums/allocation-type.c",
        "src/enums/datatype-strings.c",
        "src/enums/microkernel-type.c",
        "src/enums/node-type.c",
        "src/enums/operator-type.c",
        "src/log.c",
    ],
    hdrs = ["src/xnnpack/log.h"],
    copts = select({
        ":debug_build": [],
        "//conditions:default": xnnpack_min_size_copts(),
    }) + select({
        ":xnn_log_to_stdio_explicit_true": ["-DXNN_LOG_TO_STDIO=1"],
        "//conditions:default": [],
    }),
    defines = select({
        ":xnn_log_level_explicit_none": ["XNN_LOG_LEVEL=0"],
        ":xnn_log_level_explicit_fatal": ["XNN_LOG_LEVEL=1"],
        ":xnn_log_level_explicit_error": ["XNN_LOG_LEVEL=2"],
        ":xnn_log_level_explicit_warning": ["XNN_LOG_LEVEL=3"],
        ":xnn_log_level_explicit_info": ["XNN_LOG_LEVEL=4"],
        ":xnn_log_level_explicit_debug": ["XNN_LOG_LEVEL=5"],
        "//conditions:default": [],
    }),
    visibility = xnnpack_visibility(),
    deps = select({
        ":xnn_log_level_explicit_none": [],
        ":xnn_log_level_explicit_fatal": [],
        ":xnn_log_level_explicit_error": [],
        ":xnn_log_level_explicit_warning": [],
        ":xnn_log_level_explicit_info": [],
        ":xnn_log_level_explicit_debug": [],
        "//conditions:default": [":log_level_default"],
    }) + [
        ":allocation_type",
        ":common",
        ":microkernel_type",
        ":node_type",
        ":operator_type",
        ":xnnpack_h",
    ],
)

[
    cc_library(
        name = lib + "_microkernels",
        compatible_with = [],
        defines = xnnpack_configurable_defines(),
        hdrs_check = "strict",
        linkstatic = True,
        visibility = ["//:__subpackages__"],
        deps = xnnpack_list_sum(
            [
                xnnpack_select_if(
                    xnnpack_cond_for_arch(arch),
                    [":" + arch + "_" + lib + "_microkernels"],
                )
                for arch in xnnpack_archs()
            ],
            [],
        ) + xnnpack_select_if(
            "//build_config:hexagon",
            ["//base:system_malloc"],
        ),
    )
    for lib in ("prod", "all")
]

xnnpack_cc_library(
    name = "im2col",
    srcs = ["src/im2col.c"],
    hdrs = [
        "src/xnnpack/im2col.h",
    ],
    deps = [":common"],
)

xnnpack_cc_library(
    name = "indirection",
    srcs = ["src/indirection.c"],
    hdrs = ["src/xnnpack/indirection.h"],
    deps = [
        ":common",
        ":math",
        ":microparams",
        ":operator_h",
        ":xnnpack_h",
        "@FP16",
        "@FXdiv",
    ],
)

xnnpack_cxx_library(
    name = "packing",
    srcs = ["src/packing.cc"],
    hdrs = ["src/xnnpack/pack.h"],
    defines = xnnpack_configurable_defines(),
    deps = [
        ":common",
        ":config_hdrs",
        ":logging",
        ":math",
        ":microparams",
        ":params",
        ":unaligned",
        ":xnnpack_h",
        "@FP16",
    ] + xnnpack_if_kleidiai_enabled([
        "@KleidiAI//kai/ukernels/matmul",
        "@KleidiAI//kai/ukernels/matmul:rhs_pack_kxn_qsi4cxp_qsu4cxs1s0",
        "@KleidiAI//kai/ukernels/matmul:rhs_pack_nxk_qsi4cxp_qsu4cxs1s0",
    ]),
)

py_binary(
    name = "generate_build_identifier_py",
    srcs = ["scripts/generate-build-identifier.py"],
    main = "scripts/generate-build-identifier.py",
    tags = ["notap"],  # This should only be built as part of the related genrule.
    target_compatible_with = select({
        "//build_config:emscripten": ["@platforms//:incompatible"],
        "//conditions:default": [],
    }),
)

xnnpack_transitive_source_list(
    name = "build_identifier_ukernel_srcs",
    deps = [":prod_microkernels"],
)

genrule(
    name = "generate_build_identifier",
    srcs = [
        "src/packing.cc",
        ":build_identifier_ukernel_srcs",
    ],
    outs = ["src/build_identifier.c"],
    cmd = "$(location generate_build_identifier_py) --output $@ $(SRCS)",
    tools = [":generate_build_identifier_py"],
)

xnnpack_cc_library(
    name = "build_identifier",
    srcs = ["src/build_identifier.c"],
)

xnnpack_cc_library(
    name = "cache",
    srcs = ["src/cache.c"],
    hdrs = ["src/xnnpack/cache.h"],
    deps = [
        ":allocator",
        ":common",
        ":logging",
        ":math",
        ":memory",
        ":mutex",
        ":xnnpack_h",
    ],
)

# Define a library with just the header to remove circular dependencies:
# operator-run (compute) <-> operators.
xnnpack_cc_library(
    name = "compute_h",
    hdrs = [
        "src/xnnpack/compute.h",
    ],
    deps = [
        ":common",
        ":math",
        ":params",
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "microkernel_utils",
    srcs = ["src/microkernel-utils.c"],
    hdrs = ["src/xnnpack/microkernel-utils.h"],
    deps = [
        ":common",
        ":math",
    ],
)

# Define a library with just the header to remove circular dependencies:
# indirection <-> operators.
xnnpack_cc_library(
    name = "operator_h",
    hdrs = [
        "src/xnnpack/operator.h",
    ],
    deps = [
        ":allocator",
        ":cache",
        ":compute_h",
        ":microkernel_type",
        ":operator_type",
        ":params",
        "@pthreadpool",
    ],
)

xnnpack_cc_library(
    name = "operator_utils",
    srcs = ["src/operator-utils.c"],
    hdrs = ["src/xnnpack/operator-utils.h"],
    deps = [
        ":allocator",
        ":common",
        ":logging",
        ":math",
        ":operator_h",
        ":params",
        ":xnnpack_h",
        "@FP16",
    ],
)

xnnpack_cc_library(
    name = "operators",
    srcs = OPERATOR_SRCS,
    hdrs = [
        "src/xnnpack/compute.h",
        "src/xnnpack/operator.h",
    ],
    copts = select({
        ":debug_build": [],
        "//conditions:default": xnnpack_min_size_copts(),
    }) + select({
        ":xnn_enable_hmp_explicit_false": ["-DXNN_MAX_UARCH_TYPES=1"],
        "//conditions:default": [],
    }),
    defines = xnnpack_configurable_defines(),
    deps = [
        ":allocator",
        ":cache",
        ":common",
        ":indirection",
        ":logging",
        ":math",
        ":microkernel_configs",
        ":microkernel_type",
        ":microkernel_utils",
        ":microkernels_h",
        ":microparams_init",
        ":normalization",
        ":operator_type",
        ":operator_utils",
        ":packing",
        ":params",
        ":quantization",
        ":xnnpack_h",
        "@FP16",
        "@pthreadpool",
    ] + select({
        "//conditions:default": [],
    }),
)

xnnpack_cc_library(
    name = "subgraph",
    srcs = SUBGRAPH_SRCS + xnnpack_slinky_srcs(),
    hdrs = [
        "src/xnnpack/memory-planner.h",
        "src/xnnpack/reshape-helpers.h",
        "src/xnnpack/subgraph.h",
        "src/xnnpack/subgraph-validation.h",
    ],
    defines = xnnpack_configurable_defines(),
    deps = [
        ":allocation_type",
        ":allocator",
        ":cache",
        ":common",
        ":config_hdrs",
        ":hardware_config",
        ":internal",
        ":logging",
        ":math",
        ":memory",
        ":microkernel_type",
        ":microkernels_h",
        ":node_type",
        ":operator_type",
        ":operator_utils",
        ":operators",
        ":params",
        ":requantization",
        ":xnnpack_h",
        "@FP16",
        "@pthreadpool",
    ] + xnnpack_slinky_deps(),
)

xnnpack_cc_library(
    name = "mutex",
    srcs = [
        "src/mutex.c",
    ],
    hdrs = [
        "src/xnnpack/mutex.h",
    ],
    deps = [
        ":common",
        ":logging",
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "normalization",
    srcs = ["src/normalization.c"],
    hdrs = [
        "src/xnnpack/normalization.h",
    ],
    deps = [
        ":common",
        ":math",
        ":xnnpack_h",
    ],
)

xnnpack_cc_library(
    name = "XNNPACK",
    srcs = [
        "src/init.c",
    ],
    hdrs = [
        "include/xnnpack.h",
    ],
    copts = select({
        ":debug_build": [],
        "//conditions:default": xnnpack_min_size_copts(),
    }) + select({
        ":xnn_enable_hmp_explicit_false": ["-DXNN_MAX_UARCH_TYPES=1"],
        "//conditions:default": [],
    }),
    visibility = xnnpack_visibility(),
    deps = [
        ":allocator",
        ":build_identifier",
        ":common",
        ":config_hdrs",
        ":hardware_config",
        ":init_once",
        ":logging",
        ":math",
        ":microkernels_h",
        ":microparams",
        ":microparams_init",
        ":operators",
        ":params",
        ":subgraph",
        "@pthreadpool",
    ],
)

# Specialized XNNPACK version for TensorFlow Lite. Excludes operators currently
# not used by the TensorFlow Lite XNNPACK delegate to minimize code size.
xnnpack_cc_library(
    name = "xnnpack_for_tflite",
    srcs = [
        "src/init.c",
    ],
    hdrs = ["include/xnnpack.h"],
    copts = select({
        ":debug_build": [],
        "//conditions:default": xnnpack_min_size_copts(),
    }) + select({
        ":xnn_enable_hmp_explicit_false": ["-DXNN_MAX_UARCH_TYPES=1"],
        "//conditions:default": [],
    }),
    visibility = xnnpack_visibility(),
    deps = [
        ":allocator",
        ":hardware_config",
        ":init_once",
        ":logging",
        ":params",
        "@pthreadpool",
    ],
)

# Specialized XNNPACK version for TensorFlow.js. Excludes operators currently
# not used by the TensorFlow.js WebAssembly backend to minimize code size.
xnnpack_cc_library(
    name = "xnnpack_for_tfjs",
    srcs = [
        "src/init.c",
    ],
    hdrs = ["include/xnnpack.h"],
    copts = select({
        ":debug_build": [],
        "//conditions:default": xnnpack_min_size_copts(),
    }) + select({
        ":xnn_enable_hmp_explicit_false": ["-DXNN_MAX_UARCH_TYPES=1"],
        "//conditions:default": [],
    }),
    visibility = xnnpack_visibility(),
    deps = [
        ":allocator",
        ":hardware_config",
        ":init_once",
        ":logging",
        ":params",
        "@pthreadpool",
    ],
)

############################# End-to-end benchmarks ############################

# Helper library for benchmarks to depend on.
xnnpack_cc_library(
    name = "models_h",
    hdrs = ["src/xnnpack/models.h"],
    copts = xnnpack_std_cxxopts(),
    deps = [
        ":XNNPACK",
        ":aligned_allocator",
        ":common",
        "@FP16",
    ],
)

############################# Build configurations #############################

# Enables usage of ARM FP16 (FP16 arithmetics) scalar kernels.
config_setting(
    name = "xnn_enable_arm_fp16_scalar_explicit_true",
    define_values = {"xnn_enable_arm_fp16_scalar": "true"},
)

# Disables usage of ARM FP16 (FP16 arithmetics) scalar kernels.
config_setting(
    name = "xnn_enable_arm_fp16_scalar_explicit_false",
    define_values = {"xnn_enable_arm_fp16_scalar": "false"},
)

# Enables usage of ARM FP16 (FP16 arithmetics) vector kernels.
config_setting(
    name = "xnn_enable_arm_fp16_vector_explicit_true",
    define_values = {"xnn_enable_arm_fp16_vector": "true"},
)

# Disables usage of ARM FP16 (FP16 arithmetics) vector kernels.
config_setting(
    name = "xnn_enable_arm_fp16_vector_explicit_false",
    define_values = {"xnn_enable_arm_fp16_vector": "false"},
)

# Enables usage of ARM BF16 (BF16 arithmetics) kernels.
config_setting(
    name = "xnn_enable_arm_bf16_explicit_true",
    define_values = {"xnn_enable_arm_bf16": "true"},
)

# Disables usage of ARM BF16 (BF16 arithmetics) kernels.
config_setting(
    name = "xnn_enable_arm_bf16_explicit_false",
    define_values = {"xnn_enable_arm_bf16": "false"},
)

# Enables usage of ARM DotProd (integer dot product) kernels.
config_setting(
    name = "xnn_enable_arm_dotprod_explicit_true",
    define_values = {"xnn_enable_arm_dotprod": "true"},
)

# Disables usage of ARM DotProd (integer dot product) kernels.
config_setting(
    name = "xnn_enable_arm_dotprod_explicit_false",
    define_values = {"xnn_enable_arm_dotprod": "false"},
)

# Enables usage of ARM I8MM (8-bit integer matrix multiply accumulate) kernels.
config_setting(
    name = "xnn_enable_arm_i8mm_explicit_true",
    define_values = {"xnn_enable_arm_i8mm": "true"},
)

# Disables usage of ARM I8MM (8-bit integer matrix multiply accumulate) kernels.
config_setting(
    name = "xnn_enable_arm_i8mm_explicit_false",
    define_values = {"xnn_enable_arm_i8mm": "false"},
)

# Enables usage of Intel AVX512-VNNI-GFNI (integer dot product with gfni) kernels.
config_setting(
    name = "xnn_enable_avx512vnnigfni_explicit_true",
    define_values = {"xnn_enable_avx512vnnigfni": "true"},
)

# Disables usage of Intel AVX512-VNNI-GFNI (integer dot product with gfni) kernels.
config_setting(
    name = "xnn_enable_avx512vnnigfni_explicit_false",
    define_values = {"xnn_enable_avx512vnnigfni": "false"},
)

# Enables usage of Intel AVX512-AMX (integer matrix multiply) kernels.
config_setting(
    name = "xnn_enable_avx512amx_explicit_true",
    define_values = {"xnn_enable_avx512amx": "true"},
)

# Disables usage of Intel AVX512-AMX (integer matrix multiply) kernels.
config_setting(
    name = "xnn_enable_avx512amx_explicit_false",
    define_values = {"xnn_enable_avx512amx": "false"},
)

# Enables usage of Intel AVX512-FP16 (fp16 arithmetic) kernels.
config_setting(
    name = "xnn_enable_avx512fp16_explicit_true",
    define_values = {"xnn_enable_avx512fp16": "true"},
)

# Disables usage of Intel AVX512-FP16 (fp16 arithmetic) kernels.
config_setting(
    name = "xnn_enable_avx512fp16_explicit_false",
    define_values = {"xnn_enable_avx512fp16": "false"},
)

# Enables usage of Intel AVX-VNNI (integer dot product) kernels.
config_setting(
    name = "xnn_enable_avxvnni_explicit_true",
    define_values = {"xnn_enable_avxvnni": "true"},
)

# Disables usage of Intel AVX-VNNI (integer dot product) kernels.
config_setting(
    name = "xnn_enable_avxvnni_explicit_false",
    define_values = {"xnn_enable_avxvnni": "false"},
)

# Enables usage of Intel AVX256SKX (evex256) kernels.
config_setting(
    name = "xnn_enable_avx256skx_explicit_true",
    define_values = {"xnn_enable_avx256skx": "true"},
)

# Disables usage of Intel AVX256SKX (evex256) kernels.
config_setting(
    name = "xnn_enable_avx256skx_explicit_false",
    define_values = {"xnn_enable_avx256skx": "false"},
)

# Enables usage of Intel AVX256VNNI (evex256) kernels.
config_setting(
    name = "xnn_enable_avx256vnni_explicit_true",
    define_values = {"xnn_enable_avx256vnni": "true"},
)

# Disables usage of Intel AVX256VNNI (evex256) kernels.
config_setting(
    name = "xnn_enable_avx256vnni_explicit_false",
    define_values = {"xnn_enable_avx256vnni": "false"},
)

# Enables usage of Intel AVX256VNNIGFNI (evex256) kernels.
config_setting(
    name = "xnn_enable_avx256vnnigfni_explicit_true",
    define_values = {"xnn_enable_avx256vnnigfni": "true"},
)

# Disables usage of Intel AVX256VNNIGFNI (evex256) kernels.
config_setting(
    name = "xnn_enable_avx256vnnigfni_explicit_false",
    define_values = {"xnn_enable_avx256vnnigfni": "false"},
)

# Enables usage of Hexagon HVX kernels.
config_setting(
    name = "xnn_enable_hvx_explicit_true",
    define_values = {"xnn_enable_hvx": "true"},
)

# Disables usage of Hexagon HVX kernels.
config_setting(
    name = "xnn_enable_hvx_explicit_false",
    define_values = {"xnn_enable_hvx": "false"},
)

# Enables usage of RISC-V Vector kernels.
config_setting(
    name = "xnn_enable_riscv_vector_explicit_true",
    define_values = {"xnn_enable_riscv_vector": "true"},
)

# Disables usage of RISC-V Vector kernels.
config_setting(
    name = "xnn_enable_riscv_vector_explicit_false",
    define_values = {"xnn_enable_riscv_vector": "false"},
)

# Enables usage of RISC-V FP16 (FP16 arithmetics) vector kernels.
config_setting(
    name = "xnn_enable_riscv_fp16_vector_explicit_true",
    define_values = {"xnn_enable_riscv_fp16_vector": "true"},
)

# Disables usage of RISC-V FP16 (FP16 arithmetics) vector kernels.
config_setting(
    name = "xnn_enable_riscv_fp16_vector_explicit_false",
    define_values = {"xnn_enable_riscv_fp16_vector": "false"},
)

# Enables usage of cpuinfo library.
config_setting(
    name = "xnn_enable_cpuinfo_explicit_true",
    define_values = {"xnn_enable_cpuinfo": "true"},
)

# Disables usage of cpuinfo library.
config_setting(
    name = "xnn_enable_cpuinfo_explicit_false",
    define_values = {"xnn_enable_cpuinfo": "false"},
)

# Enables usage of the KleidiAI library.
config_setting(
    name = "xnn_enable_kleidiai_explicit_true",
    define_values = {"xnn_enable_kleidiai": "true"},
)

# Disables usage of the KleidiAI library.
config_setting(
    name = "xnn_enable_kleidiai_explicit_false",
    define_values = {"xnn_enable_kleidiai": "false"},
)

# Enables usage of assembly kernels.
config_setting(
    name = "xnn_enable_assembly_explicit_true",
    define_values = {"xnn_enable_assembly": "true"},
)

# Disables usage of assembly kernels.
config_setting(
    name = "xnn_enable_assembly_explicit_false",
    define_values = {"xnn_enable_assembly": "false"},
)

# Enables usage of sparse inference.
config_setting(
    name = "xnn_enable_sparse_explicit_true",
    define_values = {"xnn_enable_sparse": "true"},
)

# Disables usage of sparse inference.
config_setting(
    name = "xnn_enable_sparse_explicit_false",
    define_values = {"xnn_enable_sparse": "false"},
)

# Disables usage of HMP-aware optimizations.
config_setting(
    name = "xnn_enable_hmp_explicit_false",
    define_values = {"xnn_enable_hmp": "false"},
)

# Enable usage of optimized memory allocation
config_setting(
    name = "xnn_enable_memopt_explicit_true",
    define_values = {"xnn_enable_memopt": "true"},
)

# Disable usage of optimized memory allocation
config_setting(
    name = "xnn_enable_memopt_explicit_false",
    define_values = {"xnn_enable_memopt": "false"},
)

# Enables usage of slinky locality optimizations
config_setting(
    name = "slinky_enabled",
    define_values = {"xnn_use_slinky": "true"},
)

# Enables usage of mr heuristic to select microkernels.
config_setting(
    name = "xnn_enable_gemm_m_specialization_explicit_true",
    define_values = {"xnn_enable_gemm_m_specialization": "true"},
)

# Disables usage of mr heuristic to select microkernels.
config_setting(
    name = "xnn_enable_gemm_m_specialization_explicit_false",
    define_values = {"xnn_enable_gemm_m_specialization": "false"},
)

# Enables usage of DWCONV multipass kernels.
config_setting(
    name = "xnn_enable_dwconv_multipass_explicit_true",
    define_values = {"xnn_enable_dwconv_multipass": "true"},
)

# Disables usage of DWCONV multipass kernels.
config_setting(
    name = "xnn_enable_dwconv_multipass_explicit_false",
    define_values = {"xnn_enable_dwconv_multipass": "false"},
)

# Force logging to stderr/stdout
config_setting(
    name = "xnn_log_to_stdio_explicit_true",
    define_values = {"xnn_log_to_stdio": "true"},
)

# Fully disable logging
config_setting(
    name = "xnn_log_level_explicit_none",
    define_values = {"xnn_log_level": "none"},
)

# Log fatal errors only
config_setting(
    name = "xnn_log_level_explicit_fatal",
    define_values = {"xnn_log_level": "fatal"},
)

# Log fatal and non-fatal errors
config_setting(
    name = "xnn_log_level_explicit_error",
    define_values = {"xnn_log_level": "error"},
)

# Log warnings and errors
config_setting(
    name = "xnn_log_level_explicit_warning",
    define_values = {"xnn_log_level": "warning"},
)

# Log information messages, warnings and errors
config_setting(
    name = "xnn_log_level_explicit_info",
    define_values = {"xnn_log_level": "info"},
)

# Log all messages, including debug messages
config_setting(
    name = "xnn_log_level_explicit_debug",
    define_values = {"xnn_log_level": "debug"},
)

# Builds with -c dbg
config_setting(
    name = "debug_build",
    values = {
        "compilation_mode": "dbg",
    },
)

# Builds with -c opt
config_setting(
    name = "optimized_build",
    values = {
        "compilation_mode": "opt",
    },
)

######################## Composite build configurations #######################

selects.config_setting_group(
    name = "arm_fp16_scalar_enabled_by_default",
    match_any = [
        "//build_config:aarch32",
        "//build_config:aarch64",
    ],
)

alias(
    name = "arm_fp16_scalar_enabled",
    actual = select({
        ":xnn_enable_arm_fp16_scalar_explicit_true": ":xnn_enable_arm_fp16_scalar_explicit_true",
        ":xnn_enable_arm_fp16_scalar_explicit_false": ":xnn_enable_arm_fp16_scalar_explicit_true",
        "//conditions:default": ":arm_fp16_scalar_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "arm_fp16_vector_enabled_by_default",
    match_any = [
        "//build_config:aarch32",
        "//build_config:aarch64",
    ],
)

selects.config_setting_group(
    name = "arm_neondotfp16_enabled",
    match_all = [
        ":arm_fp16_vector_enabled",
        ":arm_dotprod_enabled",
    ],
)

alias(
    name = "arm_fp16_vector_enabled",
    actual = select({
        ":xnn_enable_arm_fp16_vector_explicit_true": ":xnn_enable_arm_fp16_vector_explicit_true",
        ":xnn_enable_arm_fp16_vector_explicit_false": ":xnn_enable_arm_fp16_vector_explicit_true",
        "//conditions:default": ":arm_fp16_vector_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "arm_aarch64_fp16_vector_enabled",
    match_all = [
        ":arm_fp16_vector_enabled",
        "//build_config:aarch64",
    ],
)

selects.config_setting_group(
    name = "arm_bf16_enabled_by_default",
    match_any = [
        "//build_config:aarch64",
    ],
)

alias(
    name = "arm_bf16_enabled",
    actual = select({
        ":xnn_enable_arm_bf16_explicit_true": ":xnn_enable_arm_bf16_explicit_true",
        ":xnn_enable_arm_bf16_explicit_false": ":xnn_enable_arm_bf16_explicit_true",
        "//conditions:default": ":arm_bf16_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "arm_dotprod_enabled_by_default",
    match_any = [
        "//build_config:aarch32",
        "//build_config:aarch64",
    ],
)

alias(
    name = "arm_dotprod_enabled",
    actual = select({
        ":xnn_enable_arm_dotprod_explicit_true": ":xnn_enable_arm_dotprod_explicit_true",
        ":xnn_enable_arm_dotprod_explicit_false": ":xnn_enable_arm_dotprod_explicit_true",
        "//conditions:default": ":arm_dotprod_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "arm_aarch64_dotprod_enabled",
    match_all = [
        ":arm_dotprod_enabled",
        "//build_config:aarch64",
    ],
)

selects.config_setting_group(
    name = "arm_i8mm_enabled_by_default",
    match_any = [
        "//build_config:aarch32",
        "//build_config:aarch64",
    ],
)

alias(
    name = "arm_i8mm_enabled",
    actual = select({
        ":xnn_enable_arm_i8mm_explicit_true": ":xnn_enable_arm_i8mm_explicit_true",
        ":xnn_enable_arm_i8mm_explicit_false": ":xnn_enable_arm_i8mm_explicit_true",
        "//conditions:default": ":arm_i8mm_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "arm_aarch64_i8mm_enabled",
    match_all = [
        ":arm_i8mm_enabled",
        "//build_config:aarch64",
    ],
)

selects.config_setting_group(
    name = "avx512vnnigfni_enabled_by_default",
    match_any = [
        "//build_config:x86",
    ],
)

alias(
    name = "avx512vnnigfni_enabled",
    actual = select({
        ":xnn_enable_avx512vnnigfni_explicit_true": ":xnn_enable_avx512vnnigfni_explicit_true",
        ":xnn_enable_avx512vnnigfni_explicit_false": ":xnn_enable_avx512vnnigfni_explicit_true",
        "//conditions:default": ":avx512vnnigfni_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "avx512amx_enabled_by_default",
    match_any = [
        "//build_config:x86",
    ],
)

alias(
    name = "avx512amx_enabled",
    actual = select({
        ":xnn_enable_avx512amx_explicit_true": ":xnn_enable_avx512amx_explicit_true",
        ":xnn_enable_avx512amx_explicit_false": ":xnn_enable_avx512amx_explicit_true",
        "//build_config:windows_lexan": ":xnn_enable_avx512amx_explicit_true",
        "//conditions:default": ":avx512amx_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "avx512fp16_enabled_by_default",
    match_any = [
        "//build_config:x86",
    ],
)

alias(
    name = "avx512fp16_enabled",
    actual = select({
        ":xnn_enable_avx512fp16_explicit_true": ":xnn_enable_avx512fp16_explicit_true",
        ":xnn_enable_avx512fp16_explicit_false": ":xnn_enable_avx512fp16_explicit_true",
        "//build_config:windows_lexan": ":xnn_enable_avx512fp16_explicit_true",
        "//conditions:default": ":avx512fp16_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "avxvnni_enabled_by_default",
    match_any = [
        "//build_config:x86",
    ],
)

alias(
    name = "avxvnni_enabled",
    actual = select({
        ":xnn_enable_avxvnni_explicit_true": ":xnn_enable_avxvnni_explicit_true",
        ":xnn_enable_avxvnni_explicit_false": ":xnn_enable_avxvnni_explicit_true",
        "//conditions:default": ":avxvnni_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "avx256skx_enabled_by_default",
    match_any = [
        "//build_config:x86",
    ],
)

alias(
    name = "avx256skx_enabled",
    actual = select({
        ":xnn_enable_avx256skx_explicit_true": ":xnn_enable_avx256skx_explicit_true",
        ":xnn_enable_avx256skx_explicit_false": ":xnn_enable_avx256skx_explicit_true",
        "//conditions:default": ":avx256skx_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "avx256vnni_enabled_by_default",
    match_any = [
        "//build_config:x86",
    ],
)

alias(
    name = "avx256vnni_enabled",
    actual = select({
        ":xnn_enable_avx256vnni_explicit_true": ":xnn_enable_avx256vnni_explicit_true",
        ":xnn_enable_avx256vnni_explicit_false": ":xnn_enable_avx256vnni_explicit_true",
        "//conditions:default": ":avx256vnni_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "avx256vnnigfni_enabled_by_default",
    match_any = [
        "//build_config:x86",
    ],
)

alias(
    name = "avx256vnnigfni_enabled",
    actual = select({
        ":xnn_enable_avx256vnnigfni_explicit_true": ":xnn_enable_avx256vnnigfni_explicit_true",
        ":xnn_enable_avx256vnnigfni_explicit_false": ":xnn_enable_avx256vnnigfni_explicit_true",
        "//conditions:default": ":avx256vnnigfni_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "hvx_enabled_by_default",
    match_any = [
        "//build_config:hexagon",
    ],
)

alias(
    name = "hvx_enabled",
    actual = select({
        ":xnn_enable_hvx_explicit_true": ":xnn_enable_hvx_explicit_true",
        ":xnn_enable_hvx_explicit_false": ":xnn_enable_hvx_explicit_true",
        "//conditions:default": ":hvx_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "riscv_vector_enabled_by_default",
    match_any = [
        "//build_config:riscv",
    ],
)

alias(
    name = "riscv_vector_enabled",
    actual = select({
        ":xnn_enable_riscv_vector_explicit_true": ":xnn_enable_riscv_vector_explicit_true",
        ":xnn_enable_riscv_vector_explicit_false": ":xnn_enable_riscv_vector_explicit_true",
        "//conditions:default": ":riscv_vector_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "riscv_fp16_vector_enabled_by_default",
    match_any = [
        "//build_config:riscv",
    ],
)

# Temporary disable fp16 vectors on Android
alias(
    name = "riscv_fp16_vector_enabled",
    actual = select({
        ":xnn_enable_riscv_fp16_vector_explicit_true": ":xnn_enable_riscv_fp16_vector_explicit_true",
        ":xnn_enable_riscv_fp16_vector_explicit_false": ":xnn_enable_riscv_fp16_vector_explicit_true",
        "//build_config:android": ":xnn_enable_riscv_fp16_vector_explicit_false",
        "//conditions:default": ":riscv_fp16_vector_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "cpuinfo_enabled_by_default",
    match_any = [
        "//build_config:aarch32",
        "//build_config:aarch64",
        "//build_config:x86",
    ],
)

alias(
    name = "cpuinfo_enabled",
    actual = select({
        ":xnn_enable_cpuinfo_explicit_true": ":xnn_enable_cpuinfo_explicit_true",
        ":xnn_enable_cpuinfo_explicit_false": ":xnn_enable_cpuinfo_explicit_true",
        "//conditions:default": ":cpuinfo_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "kleidiai_enabled_by_default",
    match_all = [
        "//build_config:aarch64",
        ":arm_i8mm_enabled",
    ],
)

alias(
    name = "kleidiai_enabled",
    actual = select({
        ":xnn_enable_kleidiai_explicit_true": ":xnn_enable_kleidiai_explicit_true",
        ":xnn_enable_kleidiai_explicit_false": ":xnn_enable_kleidiai_explicit_true",
        "//conditions:default": ":kleidiai_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "assembly_enabled_by_default",
    match_any = [
        "//conditions:default",
    ],
)

alias(
    name = "assembly_enabled",
    actual = select({
        ":xnn_enable_assembly_explicit_true": ":xnn_enable_assembly_explicit_true",
        ":xnn_enable_assembly_explicit_false": ":xnn_enable_assembly_explicit_true",
        "//conditions:default": ":assembly_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "sparse_enabled_by_default",
    match_any = [
        "//conditions:default",
    ],
)

alias(
    name = "sparse_enabled",
    actual = select({
        ":xnn_enable_sparse_explicit_true": ":xnn_enable_sparse_explicit_true",
        ":xnn_enable_sparse_explicit_false": ":xnn_enable_sparse_explicit_true",
        "//conditions:default": ":sparse_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "memopt_enabled_by_default",
    match_any = [
        "//conditions:default",
    ],
)

alias(
    name = "memopt_enabled",
    actual = select({
        ":xnn_enable_memopt_explicit_true": ":xnn_enable_memopt_explicit_true",
        ":xnn_enable_memopt_explicit_false": ":xnn_enable_memopt_explicit_true",
        "//conditions:default": ":memopt_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "gemm_m_specialization_enabled_by_default",
    match_any = [
        "//conditions:default",
    ],
)

alias(
    name = "gemm_m_specialization_enabled",
    actual = select({
        ":xnn_enable_gemm_m_specialization_explicit_true": ":xnn_enable_gemm_m_specialization_explicit_true",
        ":xnn_enable_gemm_m_specialization_explicit_false": ":xnn_enable_gemm_m_specialization_explicit_true",
        "//conditions:default": ":gemm_m_specialization_enabled_by_default",
    }),
)

selects.config_setting_group(
    name = "dwconv_multipass_enabled_by_default",
    match_any = [
        "//conditions:default",
    ],
)

alias(
    name = "dwconv_multipass_enabled",
    actual = select({
        ":xnn_enable_dwconv_multipass_explicit_true": ":xnn_enable_dwconv_multipass_explicit_true",
        ":xnn_enable_dwconv_multipass_explicit_false": ":xnn_enable_dwconv_multipass_explicit_true",
        "//conditions:default": ":dwconv_multipass_enabled_by_default",
    }),
)

bzl_library(
    name = "build_defs_bzl",
    srcs = ["build_defs.bzl"],
    visibility = ["//visibility:private"],
)

bzl_library(
    name = "build_params_bzl",
    srcs = ["build_params.bzl"],
    visibility = ["//visibility:private"],
)
